package com.fy56.platform.fileupload.upload;


import com.fy56.platform.fileupload.ConfigManager;
import com.fy56.platform.fileupload.define.AppInfo;
import com.fy56.platform.fileupload.define.BaseState;
import com.fy56.platform.fileupload.define.State;
import org.apache.commons.io.FileUtils;
import org.json.JSONObject;

import javax.servlet.http.HttpServletRequest;
import java.io.*;

public class StorageManager {
	public static final int BUFFER_SIZE = 8192;

	public StorageManager() {
	}

	public static State saveBinaryFile(byte[] data, String path) {
		File file = new File(path);

		State state = valid(file);

		if (!state.isSuccess()) {
			return state;
		}

		try {
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream(file));
			bos.write(data);
			bos.flush();
			bos.close();
		} catch (IOException ioe) {
			return new BaseState(false, AppInfo.IO_ERROR);
		}

		state = new BaseState(true, file.getAbsolutePath());
		state.putInfo( "size", data.length );
		state.putInfo( "title", file.getName() );
		return state;
	}

	public static State saveFileByInputStream(InputStream is, String path,
			long maxSize,HttpServletRequest request) {
		State state = null;

		File tmpFile = getTmpFile();

		byte[] dataBuf = new byte[ 2048 ];
		BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);

		try {
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE);

			int count = 0;
			while ((count = bis.read(dataBuf)) != -1) {
				bos.write(dataBuf, 0, count);
			}
			bos.flush();
			bos.close();

            //如果是图片，限制在2M以内，除了图片以外的文件限制在30M以内
            if(isImage(path)){
                maxSize = getImgMaxSize(request);
            }
            if (tmpFile.length() > maxSize) {
                tmpFile.delete();
                return new BaseState(false, AppInfo.MAX_SIZE);
            }

			state = saveTmpFile(tmpFile, path);

			if (!state.isSuccess()) {
				tmpFile.delete();
			}

			return state;
			
		} catch (IOException e) {
		}
		return new BaseState(false, AppInfo.IO_ERROR);
	}

	public static State saveFileByInputStream(InputStream is, String path) {
		State state = null;

		File tmpFile = getTmpFile();

		byte[] dataBuf = new byte[ 2048 ];
		BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);

		try {
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE);

			int count = 0;
			while ((count = bis.read(dataBuf)) != -1) {
				bos.write(dataBuf, 0, count);
			}
			bos.flush();
			bos.close();

			state = saveTmpFile(tmpFile, path);

			if (!state.isSuccess()) {
				tmpFile.delete();
			}

			return state;
		} catch (IOException e) {
		}
		return new BaseState(false, AppInfo.IO_ERROR);
	}

	private static File getTmpFile() {
		File tmpDir = FileUtils.getTempDirectory();
		String tmpFileName = (Math.random() * 10000 + "").replace(".", "");
		return new File(tmpDir, tmpFileName);
	}

	private static State saveTmpFile(File tmpFile, String path) {
		State state = null;
		String title = "";
		File targetFile = new File(path);
		if(targetFile.exists()){
			targetFile.delete();
		}
		if (targetFile.canWrite()) {
			return new BaseState(false, AppInfo.PERMISSION_DENIED);
		}
		try {
			//如果不是图片类型的文件，打成zip压缩包存到服务器上
			FileUtils.moveFile(tmpFile, targetFile);
			title = targetFile.getName();
			if(!isImage(path)){
				if(ZipTools.zip(path)){
					targetFile.delete();
					title += ".zip";
				}
			}
		} catch (IOException e) {
			return new BaseState(false, AppInfo.IO_ERROR);
		}

		state = new BaseState(true);
		state.putInfo( "size", targetFile.length() );
		state.putInfo( "title", title );

		return state;
	}

	private static State valid(File file) {
		File parentPath = file.getParentFile();

		if ((!parentPath.exists()) && (!parentPath.mkdirs())) {
			return new BaseState(false, AppInfo.FAILED_CREATE_FILE);
		}

		if (!parentPath.canWrite()) {
			return new BaseState(false, AppInfo.PERMISSION_DENIED);
		}

		return new BaseState(true);
	}

	private void doZip(String path){

	}

	/**
	 * 判断文件是否是图片
	 *
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	private static boolean isImage(String filePath) throws IOException {
		return (filePath.toLowerCase().indexOf(".png") >= 0
				|| filePath.toLowerCase().indexOf(".tif") >= 0
				|| filePath.toLowerCase().indexOf(".jpg") >= 0
				|| filePath.toLowerCase().indexOf(".jpeg") >= 0
				|| filePath.toLowerCase().indexOf(".bmp") >= 0);
	}

    /**
     * 获取图片上传大小限制
     *
     * @param request
     * @return
     */
	private static long getImgMaxSize(HttpServletRequest request){
        try{
            String configContent = readFile(getConfigPath(request));
            JSONObject jsonConfig = new JSONObject( configContent );
            return jsonConfig.getLong("imageMaxSize");
        } catch ( Exception e ) {
            return 2048000;
        }
    }

    private static String getConfigPath (HttpServletRequest request) {
	    String rootPath = request.getSession().getServletContext().getRealPath("/");
        String originalPath = "";
        if (request.getContextPath().length() > 0 ) {
            originalPath = rootPath + request.getRequestURI().substring(request.getContextPath().length());
        } else {
            originalPath = rootPath + request.getRequestURI();
        }
        File file = new File( originalPath );
        return file.getParent() + File.separator + ConfigManager.configFileName;
    }

	private static String readFile ( String path ) throws IOException {
		StringBuilder builder = new StringBuilder();
		try {
			InputStreamReader reader = new InputStreamReader( new FileInputStream( path ), "UTF-8" );
			BufferedReader bfReader = new BufferedReader( reader );
			String tmpContent = null;
			while ( ( tmpContent = bfReader.readLine() ) != null ) {
				builder.append( tmpContent );
			}
			bfReader.close();
		} catch ( UnsupportedEncodingException e ) {
			// 忽略
		}
		return builder.toString().replaceAll( "/\\*[\\s\\S]*?\\*/", "" );
	}

}
